home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / ungepackte_daten / 1993 / 3 / 02 / automobil / bilanz / source / source.ampk / BilanzFunk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-01  |  19.5 KB  |  701 lines

  1. #include "Bilanz.h"
  2. #include <libraries/dosextens.h>
  3. #include <clib/console_protos.h>
  4.  
  5. void GetMessage(void)
  6. {
  7.   while (!(message = (struct IntuiMessage *) GetMsg(win->UserPort))) {
  8.     Wait(1L << win->UserPort->mp_SigBit);
  9.   }
  10.   class     = message->Class;
  11.   code      = message->Code;
  12.   qualifier = message->Qualifier;
  13.   adr       = message->IAddress;
  14.   ReplyMsg((struct Message *)message);
  15. }
  16.  
  17. void GetMessageClass(void)
  18. {
  19.   if (message = (struct IntuiMessage *) GetMsg(win->UserPort)) {
  20.     class = message->Class;
  21.     code  = message->Code;
  22.     qualifier = message->Qualifier;
  23.     ReplyMsg((struct Message *)message);
  24.   }
  25. }
  26.  
  27. void WaitNoButton(void)    /* waits until no button is pressed */
  28. {
  29.   do GetMessageClass();
  30.   while (qualifier & 0x6000L);
  31. }
  32.  
  33. void Frame (long x1, long y1, long x2, long y2, long color)
  34. {
  35.   SetAPen(RP,color); Move(RP,x1,y1);
  36.   Draw(RP,x2,y1); Draw(RP,x2,y2);
  37.   Draw(RP,x1,y2); Draw(RP,x1,y1);
  38. }
  39.  
  40. void Print (char *s, long x, long y)
  41. {
  42.   Move(RP, x, y);
  43.   Text(RP, s, (long)strlen(s));
  44. }
  45.  
  46.  
  47. void ltos (long n, char *s, short w, short point, char fill)
  48.     /* convert integer to string:
  49.        w     = width = stringlength
  50.        point = 0 -> no dec-point
  51.          > 0 -> dec-point insert at position <point>
  52.        fill  = character for leading zeros */
  53. {
  54.   short i, minus = 0;
  55.   i = w; point--;
  56.   s[i--] = 0;
  57.   if (point >= 0) s[point] = '.';
  58.   if (n<0) { minus = 1; n = -n; }
  59.   do {
  60.     s[i--] = n % 10 + '0';
  61.     if (point == i) i--;
  62.   } while (((n /= 10) > 0) && (i >= 0));
  63.   if (n>0) s[0] = '!';
  64.   if (minus)
  65.     if (i>=0) s[i--] = '-';
  66.     else      s[0] = '!';
  67.   while (i>=0) {
  68.     if (i == point) s[i] = '.';
  69.     else if (i == (point-1)) s[i] = '0';
  70.     else if ((i > point) && (point > 0)) s[i] = '0';
  71.     else s[i] = fill;
  72.     i--;
  73.   }
  74. }
  75.  
  76.  
  77. double stof (unsigned char *s)    /* convert string to real */
  78. {
  79.   short i=0, minus=0, ok=1;
  80.   double f=0.0, n=10.0;
  81.   /* read whitespaces and minus */
  82.   while (s[i] && !(s[i]>=48 && s[i]<=57 || s[i]=='.' || s[i]==',')) {
  83.     if (s[i++]=='-') minus=1-minus; /* two minus = plus */
  84.   }
  85.   do { /* numbers befor decpoint */
  86.     if (s[i]>=48 && s[i]<=57) f=f*10.0+(s[i]-48);
  87.     else if (s[i]=='.' || s[i]==',') ok=2;
  88.     else ok=0;
  89.     i++;
  90.   } while(ok==1);
  91.   while (ok==2) { /* numbers behind decpoint */
  92.     if (s[i]>=48 && s[i]<=57) f=f+(double)(s[i]-48)/n;
  93.     else ok=0;
  94.     i++; n*=10.0;
  95.   }
  96.   if (minus) f=-f;
  97.   return(f);
  98. }
  99.  
  100.  
  101. long round (double real)
  102. {
  103.   if (real < 0.0) return((long)(real - 0.5));
  104.   else            return((long)(real + 0.5));
  105. }
  106.  
  107.  
  108. #define UP 65
  109. #define DN 66
  110. #define LE 68
  111. #define RI 67
  112.  
  113. short ReadText (unsigned char *s, long x, long y, short max, short startpos,
  114.                 char ins, unsigned char *abbruch,
  115.                 long f0, long f1, long f2, long f3)
  116. /*
  117.    s       = übergebener String
  118.    x, y    = Position auf dem Bildschirm
  119.    max     = es können maximal max Zeichen in s eingegeben werden; ist der
  120.              übergebene String länger, wird der Rest abgeschnitten
  121.    startpos= Position des Cursors im String bei Aufruf der Routine
  122.              Ein Wert < 1 steht für letzte Position
  123.    ins     = 0 -> Overwrite-Modus
  124.            = 1 -> Insert-Modus
  125.    abbruch = String, der alle Abbruchwerte nach RAWKEY enthält (z.B. 
  126.              abbruch[] = {13,27,9,1,4,0};
  127.              abbruch sollte mindestens das RETURN-Zeichen und
  128.              die 0 als String-Abschluß enthalten.
  129.              1 im String steht für Abbruch bei Maustaste
  130.              2             "               bei Erreichen der max. Länge
  131.              3             "               bei CursorLeft/Right am
  132.                                              Anfang bzw. Ende des Strings
  133.              4             "               bei CursorUp/Down
  134.              5             "               bei F-Tasten
  135.    f0      = Hintergrundfarbe
  136.    f1      = Zeichenfarbe
  137.    f2      = Cursorfarbe
  138.    f3      = Zeichenfarbe im Cursor
  139.    Return-Wert ist der Tastatur-Code von Sondertasten, ansonsten 0
  140.  
  141.    changeflag ist eine globale Variable, um innerhalb des Programms
  142.               festzustellen, ob Änderungen im String vorgenommen wurden.
  143.               Die entsprechenden Zeilen können aber auch gelöscht werden.
  144. */
  145. {
  146. #define INPUTLEN 16L
  147.   struct InputEvent inputEvent = { 0, IECLASS_RAWKEY,0, 0,0 };
  148.   short i, j, asc, laenge = strlen(s), laengeabbr = strlen(abbruch);
  149.   char str[2], fertig=0, mausabbruch=0, laengenabbruch=0,
  150.        abbruchLeRi=0, abbruchUpDn=0, abbruchF=0, nop;
  151.   byte inputPuffer[INPUTLEN];
  152.  
  153.   if (laenge>max) s[laenge]=0;
  154.   i = (--startpos < 0) ? laenge : startpos;
  155.   if (i >= max) i = max-1;
  156.   SetAPen(RP,f1); SetBPen(RP,f0);
  157.   Print(s,x,y);
  158.   SetAPen(RP,f3); SetBPen(RP,f2);
  159.   str[0]=(s[i]==0)? 32 : s[i]; str[1]=0;
  160.   Move(RP,x+8*i,y); Text(RP,str,1L);
  161.   /* Abbruchbedingungen registrieren */
  162.   for (j=0; j<laengeabbr; j++) {
  163.     if      (abbruch[j]==1) mausabbruch=1;
  164.     else if (abbruch[j]==2) laengenabbruch=1;
  165.     else if (abbruch[j]==3) abbruchLeRi=1;
  166.     else if (abbruch[j]==4) abbruchUpDn=1;
  167.     else if (abbruch[j]==5) abbruchF=1;
  168.   }
  169.   do {
  170.     GetMessage();
  171.     nop=1;
  172.     if ((class & RAWKEY) && !(code & IECODE_UP_PREFIX)) {
  173.       inputEvent.ie_Code = code;
  174.       inputEvent.ie_Qualifier = qualifier;
  175.       if (RawKeyConvert(&inputEvent,inputPuffer,INPUTLEN,NULL) > 0) {
  176.         asc = inputPuffer[0];
  177.         nop = j = 0;
  178.         while (j < laengeabbr && !fertig)
  179.           if (asc==abbruch[j++]) fertig=1;
  180.         if (!fertig) {
  181.           if (asc>31 && asc<127 || asc==228 || asc==246 || asc==252 ||
  182.               asc==223 || asc==196 || asc==214 || asc==220) {
  183.             if (ins==1 && laenge<max) {
  184.               j= ++laenge;
  185.               while (j>i) { s[j]=s[j-1]; j--; }
  186.               s[i]=asc;
  187.               if ((i+1)<max) i++;
  188.               else if (laengenabbruch) fertig=2;
  189.               changeflag = 1;
  190.             }
  191.             else if (ins==0) {
  192.               if (i==laenge) { laenge++; s[laenge]=0; }
  193.               s[i]=asc;
  194.               if ((i+1)<max) i++;
  195.               else if (laengenabbruch) fertig=2;
  196.               changeflag = 1;
  197.             }
  198.           }
  199.           else if (asc==8 && i>0) {
  200.             j= --i;
  201.             while (j<laenge) { s[j]=s[j+1]; j++; }
  202.             laenge--;
  203.             changeflag = 1;
  204.           }
  205.           else if (asc==127 && i<laenge) {
  206.             j=i;
  207.             while(j<laenge) { s[j]=s[j+1]; j++; }
  208.             laenge--;
  209.             changeflag = 1;
  210.           }
  211.           else if (asc==155) {
  212.             asc=inputPuffer[1];
  213.             if (abbruchF && asc>=48 && asc<=57) fertig=1;
  214.             else if (asc==RI && i<laenge && (i+1)<max) i++;
  215.             else if (asc==RI && (i==laenge || i==max-1) && abbruchLeRi) fertig=1;
  216.             else if (asc==LE && i>0) i--;
  217.             else if (asc==LE && i==0 && abbruchLeRi) fertig=1;
  218.             else if (abbruchUpDn && (asc==UP || asc==DN)) fertig=1;
  219.             else if (asc==UP) i=0;
  220.             else if (asc==DN) {
  221.               if (laenge==max) i = max-1;
  222.               else             i = laenge;
  223.             }
  224.           }
  225.         }
  226.       }
  227.     }
  228.     else if (class & INTUITICKS) {
  229.       SetBPen(RP,0); PrintDate();
  230.     }
  231.     /* Abbruch bei Drücken der linken Maustaste: */
  232.     else if (qualifier & 0x4000) {
  233.       fertig=1; asc=1, nop=0;
  234.     }
  235.     if (!nop) {
  236.       SetAPen(RP,f1); SetBPen(RP,f0);
  237.       Print(s,x,y);
  238.       if (laenge<max) Print(" ",x+laenge*8,y);
  239.       if (asc==8 && i==laenge) Print(" ",x+laenge*8+8,y);
  240.       if (!fertig) { /* Cursor zeichnen */
  241.         SetAPen(RP,f3); SetBPen(RP,f2);
  242.         str[0]=(s[i]==0)? 32 : s[i]; str[1]=0;
  243.         Move(RP,x+8*i,y); Text(RP,str,1L);
  244.       }
  245.     }
  246.   } while (!fertig);
  247.   SetAPen(RP,1L); SetBPen(RP,0);
  248.   if (fertig==2) return(0);
  249.   else return(asc);
  250. }
  251.  
  252.  
  253. void GetClock(void)
  254. { unsigned char clock[8];
  255.   getclk(clock);
  256.   time.hour = clock[4];
  257.   time.min  = clock[5];
  258.   time.sec  = clock[6];
  259.   time.day  = clock[3];
  260.   time.month= clock[2];
  261.   time.year = clock[1] + 1980;
  262.   strcpy(time.weekday,Weekday[clock[0]]);
  263. }
  264.  
  265. void PrintTime(short x, short y)
  266. { unsigned char s[5], o=0;
  267.   SetAPen(RP,1L);
  268.   ltos(time.hour,s,2,0,' '); Print(s,x,y+10); Print(":",x+16,y+10);
  269.   ltos(time.min,s,2,0,'0'); Print(s,x+24,y+10); Print(":",x+40,y+10);
  270.   ltos(time.sec,s,2,0,'0'); Print(s,x+48,y+10);
  271.   Print(time.weekday,x,y);
  272.   Print(",",x+16,y);
  273.   ltos(time.day,s,2,0,' ');
  274.   if (s[0]!=' ') x += 8;
  275.   Print(s,x+24,y); Print(".",x+40,y);
  276.   ltos(time.month,s,2,0,' ');
  277.   if (s[0]==' ') { s[0] = s[1]; s[1] = 0; }
  278.   else o = 8;
  279.   Print(s,x+48,y); Print(".",x+56+o,y);
  280.   ltos(time.year,s,4,0,' '); s[0]=s[2]; s[1]=s[3]; s[2]=0; Print(s,x+64+o,y);
  281. }
  282.  
  283. void PrintDate(void)
  284. {
  285.   GetClock(); PrintTime(535,23);
  286. }
  287.  
  288.  
  289. void StatusClr(void)    /* clear statusline */
  290. { int i;
  291.   for (i=1; i<=13; i++) {
  292.     ScrollRaster(RP,0L,1L,70L,82L,630L,94L);
  293.     Delay(1);
  294.   }
  295. }
  296.  
  297. void StatusText(char s[200], char modus, long color)    /* print text in statusline */
  298. { int i;
  299.   status = 1; counter = 30;
  300.   if (strlen(s) > 69) s[69]=0;
  301.   if (modus) {
  302.     for (i=1; i<=12; i++) {
  303.       ScrollRaster(RP,0L,1L,70L,82L,630L,94L);
  304.       Delay(1);
  305.     }
  306.   }
  307.   SetAPen(RP,color);
  308.   Print(s,72,91);
  309.   if (modus) Delay((modus-1)*60);
  310. }
  311.  
  312. int power2(int i)
  313. { int n=1;
  314.   while(i>0) {n *= 2; i--; }
  315.   return(n);
  316. }
  317.  
  318.  
  319. short InsertEntry(struct Entry entry, int month)
  320. {
  321.   struct Entry *new, *cur, *old;
  322.   if (!(new = (struct Entry *) AllocMem(sizeof(struct Entry),0))) return(0);
  323.   strcpy(new->area,entry.area);
  324.   strcpy(new->title,entry.title);
  325.   new->date  = entry.date;
  326.   new->costs = entry.costs;
  327.   new->next  = 0;
  328.   old = cur = year->month[month].first;
  329.   if (!cur) year->month[month].first = new;    /* first entry */
  330.   else {
  331.     while (cur->date <= new->date && cur->next) {
  332.       old = cur; cur = cur->next;
  333.     }
  334.     if (new->date < cur->date) {    /* insert entry before current */
  335.       if (old==cur) {            /* new entry is the first in the list*/
  336.         year->month[month].first = new;
  337.         new->next = cur;
  338.       }
  339.       else {
  340.         old->next = new;
  341.         new->next = cur;
  342.       }
  343.     }
  344.     else {                /* append entry */
  345.       cur->next = new;
  346.     }
  347.   }
  348.   return(1);
  349. }
  350.  
  351. void DeleteEntry(struct Entry *entry)
  352. {
  353.   struct Entry *old, *cur;
  354.   old = cur = year->month[curmonth].first;
  355.   while (cur != entry) {
  356.     old = cur; cur = cur->next;
  357.   }
  358.   if (old == cur) year->month[curmonth].first = cur->next;
  359.   else            old->next = cur->next;
  360.   FreeMem(cur,sizeof(struct Entry));
  361. }
  362.  
  363. short InsertYear(struct Year **ptr)
  364. { short n;
  365.   struct Year *new, *cur, *old;
  366.   cur = firstyear; old = 0;
  367.   while (cur && cur->year < curyear) { old = cur; cur = cur->next; }
  368.   if (cur && cur->year == curyear) return(-1);   /* year exists already */
  369.   new = (struct Year *) AllocMem(sizeof(struct Year),0);
  370.   if (new) {
  371.     new->year = curyear;
  372.     new->income = new->expend = 0;
  373.     for (n=1; n<=12; n++) {
  374.       new->month[n].income = new->month[n].expend = new->month[n].number = 0;
  375.       new->month[n].first = 0;
  376.     }
  377.     if (!old) { new->next = firstyear; firstyear = new; }
  378.     else      { old->next = new; new->next = cur; }
  379.     *ptr = new;
  380.     return(1);
  381.   }
  382.   else return(0);
  383. }
  384.  
  385. void DeleteYears(void)    /* free memory */
  386. {
  387.   struct Year *nextyear;
  388.   struct Entry *entry, *nextentry;
  389.   year = firstyear;
  390.   while (year) {
  391.     nextyear = year->next;
  392.     for (curmonth=1; curmonth<=12; curmonth++) {
  393.      entry = year->month[curmonth].first;
  394.       while (entry) {
  395.         nextentry = entry->next;
  396.         FreeMem(entry,sizeof(struct Entry));
  397.         entry = nextentry;
  398.       }
  399.     }
  400.     FreeMem(year,sizeof(struct Year));
  401.     year = nextyear;
  402.   }
  403. }
  404.  
  405. int MouseIn(int x1, int y1, int x2, int y2) /* mouse in frame ?*/
  406. {
  407.   if (win->MouseX >= x1 && win->MouseX <= x2 &&
  408.       win->MouseY >= y1 && win->MouseY <= y2)
  409.     return(1);
  410.   else return(0);
  411. }
  412.  
  413. int MouseInFrame(int x1, int y1, int x2, int y2) /* mouse pressed in frame ?*/
  414. {
  415.   if (qualifier & 0x4000L &&
  416.       win->MouseX >= x1 && win->MouseX <= x2 &&
  417.       win->MouseY >= y1 && win->MouseY <= y2)
  418.     return(1);
  419.   else return(0);
  420. }
  421.  
  422.  
  423. void Gadget(unsigned char *s, int x1, int y1, int x2, int y2, int on)
  424.     /* draws own gadgets because updating is much faster (and easier)
  425.        draws frame around x1,y1,x2,y2
  426.        on = 1  => gadget is pressed
  427.        on = 0  => gadget off */
  428. {
  429.     SetAPen(RP, 2L - on);
  430.     Move(RP,x1-2,--y1); Draw(RP,x1-2,y2+1); Draw(RP,--x1,y2);
  431.     Draw(RP,x1,y1); Draw(RP,++x2,y1);
  432.     SetAPen(RP, 1L + on);
  433.     Move(RP,x2+1,++y2); Draw(RP,x2+1,y1); Draw(RP,x2,++y1);
  434.     Draw(RP,x2,y2); Draw(RP,x1,y2);
  435.     Print(s, (x1+x2+1)/2 - strlen(s)*4, (y1+y2)/2 + 3);
  436. }
  437.  
  438. int FilterCmp(unsigned char s[41])    /* check if text in filter */
  439. { int i, fn=1;
  440.   for (i=0; i<FILTER; i++) {
  441.     if ((filter & fn) && strcmp(year->filtertext[i],s)==0) {
  442.       if (include) return(1);
  443.       else         return(0);
  444.     }
  445.     fn *= 2;
  446.   }
  447.   if (include) return(0);
  448.   else         return(1);
  449. }
  450.  
  451. void UpdateFilter(int nr)
  452.     /* nr = -1  =>  update all filter
  453.        nr >= 0  =>  update filter no. nr */
  454. {
  455.   int i, d;
  456.   i = (nr < 0) ? 0 : nr;
  457.   do {
  458.     d = i * 74 + 64;
  459.     SetAPen(RP,0L);
  460.     RectFill(RP,d,66L,d+69L,76L);
  461.     Gadget(year->filtername[i], d,66,d+69,76, filterflag[i]);
  462.     i++;
  463.   } while (nr < 0 && i<FILTER);
  464. }
  465.  
  466. void FilterSwitch(int nr)    /* filter on/off */
  467. {
  468.   if (filterflag[nr]) {
  469.     filter &= 65535-power2(nr);
  470.     filterflag[nr] = 0;
  471.   }
  472.   else {
  473.     filter |= power2(nr);
  474.     filterflag[nr] = 1;
  475.   }
  476.   UpdateFilter(nr);
  477. }
  478.  
  479. void FilterChange(int nr)    /* change text of filter */
  480. { int line=0, ok=1, w;
  481.   OutClr(); SetAPen(RP,1L);
  482.   Print("Filtereintrag ändern:",50,120);
  483.   Print("Gadget-Name:",50,130);
  484.   Print("Filter-Text:",50,140); Print(year->filtertext[nr],150,140);
  485.   while (ok) {
  486.     if (!line) {
  487.       w = ReadText(year->filtername[nr],150,130,8,1,INS,stopRead,0,1,2,1);
  488.       if (w == 27) ok = 0;
  489.       if (w != 1) line = 1;
  490.     }
  491.     else {
  492.       w = ReadText(year->filtertext[nr],150,140,20,1,INS,stopRead,0,1,2,1);
  493.       if (w == 65) line = 0;
  494.       else if (w == 1) line = 1;
  495.       else ok = 0;
  496.     }
  497.   }
  498.   UpdateFilter(nr);
  499.   OutStart();
  500.   StatusYear(1);
  501. }
  502.  
  503.  
  504. int Count(int step)
  505.     /* step back/forward one entry (depend on filter) or
  506.        jump to first/last entry */
  507. {
  508.   if (step<=0 && !count) return(0);
  509.   else if (step==2) { if (number-MAXLINE <= 0) return(0); }
  510.   if (!filter) {
  511.     if (step==0) { count = 0; return(1); }
  512.     else if (step==2) {
  513.       if (count < number-MAXLINE) {
  514.         count = number-MAXLINE; return(1);
  515.       }
  516.       else return(0);
  517.     }
  518.     else if (step==1) {
  519.       if (number-count-MAXLINE <= 0) return(0);
  520.     }
  521.     count += step; return(1);
  522.   }
  523.   else {
  524.     struct Entry *entry;
  525.     int i, j;
  526.     entry = year->month[curmonth].first;
  527.     if (step==0) {
  528.       i = 0;
  529.       while (entry && !FilterCmp(entry->area)) {
  530.         entry = entry->next;
  531.         i++;
  532.       }
  533.       if (count!=i) { count = i; return(1); }
  534.       else return(0);
  535.     }
  536.     else if (step==-1) {
  537.       j = -1;
  538.       for (i=0; i<count; i++) {
  539.         if (FilterCmp(entry->area)) j = i;
  540.         entry = entry->next;
  541.       }
  542.       if (j>=0) { count = j; return(1); }
  543.       else return(0);
  544.     }
  545.     else if (step==1) {
  546.       j = 0;
  547.       for (i=0; i<=count; i++) {
  548.         if (FilterCmp(entry->area)) j++;
  549.         entry = entry->next;
  550.       }
  551.       if (number-j-MAXLINE < 0) return(0);
  552.       while (entry && !FilterCmp(entry->area)) {
  553.         entry = entry->next;
  554.         i++;
  555.       }
  556.       if (entry) { count = i; return(1); }
  557.       else return(0);
  558.     }
  559.     else { /* step==2 */
  560.       j = number-MAXLINE; i = 0;
  561.       while (j) {
  562.         if (FilterCmp(entry->area)) j--;
  563.         entry = entry->next; i++;
  564.       }
  565.       while (!FilterCmp(entry->area)) {
  566.         entry = entry->next; i++;
  567.       }
  568.       if (count!=i) { count = i; return(1); }
  569.       else return(0); 
  570.     }
  571.   }
  572. }
  573.  
  574.  
  575. short LoadData(unsigned char *filename)
  576. {
  577.   FILE *fp;
  578.   int i, j, n, mon, ok = 1;
  579.   unsigned char s[100], date[6];
  580.   struct Entry entry;
  581.   /* form of file :
  582.        filtername1,filtername2,..., (max. 8)
  583.        filtertext1,...
  584.        tt.mm,area1
  585.        12345,title1
  586.        tt.mm,area2 ... */
  587.   for (i=0; i<FILTER; i++) year->filtername[i][0] = year->filtertext[i][0] = 0;
  588.   if (fp = fopen(filename,"r")) {
  589.     SetAPen(RP,0L); RectFill(RP,70L,82L,630L,94L);
  590.     strcpy(s,"Lade "); strcat(s,filename); strcat(s,"          ");
  591.     StatusText(s,0,1);
  592.     fgets(s,sizeof(s),fp); s[strlen(s)-1] = 0;
  593.     j = n = 0;
  594.     for (i=0; i<=strlen(s); i++) {
  595.       if (s[i] == ',' || s[i] == 0) {
  596.         year->filtername[n][j] = 0; j = 0;
  597.         if (n<FILTER) n++;
  598.       }
  599.       else if (j<8) year->filtername[n][j++] = s[i];
  600.     }
  601.     fgets(s,sizeof(s),fp); s[strlen(s)-1] = 0;
  602.     j = n = 0;
  603.     for (i=0; i<=strlen(s); i++) {
  604.       if (s[i] == ',' || s[i] == 0) {
  605.         year->filtertext[n][j] = 0; j = 0;
  606.         if (n<FILTER) n++;
  607.       }
  608.       else if (j<20) year->filtertext[n][j++] = s[i];
  609.     }
  610.     do {
  611.       n = fscanf(fp,"%5s,",date);
  612.       if (n==1) {
  613.         fgets(s,sizeof(s),fp); s[strlen(s)-1] = 0;
  614.         if (strlen(s) <= 20) strcpy(entry.area,s);
  615.         else { ok = 0; StatusText("Fehler: zu langer Bereichsname!",2,2); }
  616.         n = fscanf(fp,"%ld,",&entry.costs);
  617.         if (n != 1) ok = 0;
  618.         fgets(s,sizeof(s),fp); s[strlen(s)-1] = 0;
  619.         if (strlen(s) <= 40) strcpy(entry.title,s);
  620.         else { ok = 0; StatusText("Fehler: zu langer Titel!",2,2); }
  621.         if (ok) {
  622.           s[0] = date[0]; s[1] = date[1]; s[2] = 0; /* read day */
  623.           entry.date = atoi(s);
  624.           s[0] = date[3]; s[1] = date[4]; s[2] = 0; /* read month */
  625.           mon = atoi(s);
  626.           if (mon > 0 && mon <= 12) {
  627.             if (ok = InsertEntry(entry,mon)) {
  628.               if (entry.costs > 0) year->month[mon].income += entry.costs;
  629.               else                 year->month[mon].expend += labs(entry.costs);
  630.               year->month[mon].number++;
  631.             }
  632.             else StatusText("Nicht genug Speicherplatz!",1,2);
  633.           }
  634.           else { ok = 0; StatusText("Fehler: Falscher Monat!",2,2); }
  635.         }
  636.         if (!ok) {
  637.           strcpy(s,"Habe "); strcat(s,filename);
  638.           strcat(s," nicht vollständig geladen!"); StatusText(s,1,2);
  639.         }
  640.       }
  641.       else {
  642.         ok = 0;
  643.         strcpy(s,"Habe "); strcat(s,filename); strcat(s," geladen");
  644.         StatusText(s,0,1);
  645.       }
  646.     } while (ok);
  647.     fclose(fp);
  648.     for (n=1; n<=12; n++) {
  649.       year->income += year->month[n].income;
  650.       year->expend += year->month[n].expend;
  651.     }
  652.     return(1);
  653.   }
  654.   else {
  655.     strcpy(s,"Kann "); strcat(s,filename); strcat(s," nicht öffnen!");
  656.     StatusText(s,1,1); return(0);
  657.   }
  658. }
  659.  
  660. short SaveData(unsigned char *filename)
  661. {
  662.   FILE *fp;
  663.   struct Entry *entry;
  664.   unsigned char bakfile[100], s[200], date[6], mon, i;
  665.   date[2] = '.'; date[5] = 0;
  666.   strcpy(bakfile,filename);
  667.   strcat(bakfile,".bak");
  668.   StatusClr();
  669.   if (DeleteFile(bakfile)) {
  670.     strcpy(s,"Lösche "); strcat(s,bakfile); StatusText(s,0,1); Delay(10);
  671.   }
  672.   if (Rename(filename,bakfile)) {
  673.     strcpy(s,"Rename "); strcat(s,filename); strcat(s," as ~.bak");
  674.     StatusText(s,0,1); Delay(10);
  675.   }
  676.   if (fp = fopen(filename,"w")) {
  677.     strcpy(s,filename); strcat(s," speichern..."); StatusText(s,1,1);
  678.     for (i=0; i<FILTER-1; i++) fprintf(fp,"%s,",year->filtername[i]);
  679.     fprintf(fp,"%s\n",year->filtername[FILTER-1]);
  680.     for (i=0; i<FILTER-1; i++) fprintf(fp,"%s,",year->filtertext[i]);
  681.     fprintf(fp,"%s\n",year->filtertext[FILTER-1]);
  682.     for (mon=1; mon<=12; mon++) {
  683.       ltos(mon,s,2,0,'0'); date[3] = s[0]; date[4] = s[1];
  684.       entry = year->month[mon].first;
  685.       while (entry) {
  686.         ltos(entry->date,s,2,0,'0'); date[0] = s[0]; date[1] = s[1];
  687.         fprintf(fp,"%5s,%s\n%8ld,%s\n",date,entry->area,
  688.                            entry->costs,entry->title);
  689.         entry = entry->next;
  690.       }
  691.     }
  692.     fclose(fp);
  693.     strcpy(s,filename); strcat(s," gespeichert "); StatusText(s,0,1);
  694.     return(1);
  695.   }
  696.   else {
  697.     strcpy(s,"Kann "); strcat(s,filename); strcat(s," nicht öffnen!");
  698.     StatusText(s,1,2); Delay(200); return(0);
  699.   }
  700. }
  701.